import 'dart:convert';

import 'package:common_utils/common_utils.dart' hide LogUtil;
import 'package:get/get.dart';
import 'package:orginone/components/Tip/ToastUtils.dart';
import 'package:orginone/dart/base/common/emitter.dart';
import 'package:orginone/dart/base/common/mutex.dart';
import 'package:orginone/dart/base/model.dart';
import 'package:orginone/dart/base/schema.dart';
import 'package:orginone/dart/core/provider/auth.dart';
import 'package:orginone/dart/core/provider/session.dart';
import 'package:orginone/dart/core/target/base/target.dart';
import 'package:orginone/dart/core/target/person.dart';
import 'package:orginone/dart/core/work/box.dart';
import 'package:orginone/main.dart';
import 'package:orginone/utils/log/log_util.dart';
import '../../../routers/pages.dart';
import '../../../routers/router_const.dart';
import '../../base/common/systemError.dart';
import '../thing/standard/application.dart';
import '../work/provider.dart';
import 'home.dart';

/// 当前用户提供层
class DataProvider with EmitterMixin, Mutex {
  late AuthProvider _auth;
  bool _inited = false;

  ///当前用户
  late IPerson? _user;

  ///暂存箱
  late IBoxProvider? _box;

  ///办事提供层
  final Rxn<IWorkProvider> _work = Rxn();

  ///沟通
  IChatProvider? _chatProvider;

  ///首页提供层
  late HomeProvider? _home;

  var myApps = <Map<IApplication, ITarget>>[].obs;

  DataProvider() {
    _user = null;
    _auth = AuthProvider((data) async {
      await _loadUser(data);
    });
  }

  /// 授权方法
  AuthProvider get auth {
    return _auth;
  }

  /// 当前用户
  IPerson? get user {
    return _user;
  }

  /// 办事提供层
  IWorkProvider? get work {
    return _work.value;
  }

  /// 主页提供层
  HomeProvider? get home {
    return _home;
  }

  /// 暂存提供层
  IBoxProvider? get box {
    return _box;
  }

  ///沟通提供层
  IChatProvider? get chatProvider {
    return _chatProvider;
  }

  /// 是否完成初始化
  bool get inited {
    return _inited;
  }

  List<ITarget> get targets {
    final List<ITarget> targets = [];
    if (null != _user) {
      targets.addAll(_user!.targets);
      for (final company in _user!.companys) {
        targets.addAll(company.targets);
      }
    }
    return targets;
  }

  /// 登录
  /// @param account 账户
  /// @param password 密码
  @Deprecated("改造到AuthProvider，参考react")
  Future<dynamic> login(String account, String password) async {
    _inited = false;
    ResultType res = await stopWatch<ResultType>("用户$account登陆", () async {
      return await kernel.login(account, password);
    });
    XLogUtil.dd('>>>>>>User.login ${jsonEncode(res)}');
    if (res.success) {
      _loadUser(XTarget.fromJson(res.data["target"]));
    }
    // _inited = true;
    return res;
  }

  /// 刷新token
  @Deprecated("改造到AuthProvider，参考react")
  Future<dynamic> refreshToken(String account, String password) async {
    // _inited = false;
    ResultType res = await stopWatch<ResultType>("刷新token", () async {
      return await kernel.login(account, password);
    });
    if (res.success) {
      // _inited = true;
      wakeUp();
    } else {
      ToastUtils.showMsg(msg: '登陆失败：${jsonEncode(res)}');
      XLogUtil.e('登陆失败:${jsonEncode(res)}');
      res = await refreshToken(account, password);
    }
    return res;
  }

  /// @param phoneNumber 手机号
  /// @param verifyCode 验证码
  /// @param dynamicId 动态码
  @Deprecated("改造到AuthProvider，参考react")
  Future<dynamic> verifyCodeLogin(
      String account, String password, String dynamicId) async {
    var res = await kernel.verifyCodeLogin(account, password, dynamicId);
    if (res.success) {
      _loadUser(XTarget.fromJson(res.data["target"]));
    }
    return res;
  }

  /// 二维码认证登录
  /// @param connectionId 二维码认证内容
  @Deprecated("改造到AuthProvider，参考react")
  Future<ResultType> qrAuth(String connectionId) async {
    var res = await kernel.qrAuth(connectionId);
    return res;
  }

  /// 注册用户
  /// @param {RegisterType} params 参数
  @Deprecated("改造到AuthProvider，参考react")
  register(RegisterType params) async {
    var res = await kernel.register(params);
    if (res.success) {
      _loadUser(res.data.target);
    }
    return res;
  }

  /// 私钥变更密码
  /// @param account 账号
  /// @param password 密码
  /// @param privateKey 私钥
  /// @returns
  @Deprecated("改造到AuthProvider，参考react")
  Future<ResultType> resetPasswordForDynamicCode(
    String account,
    String dynamicId,
    String dynamicCode,
    String password,
  ) async {
    return await kernel.resetPasswordForDynamicCode(
        account, dynamicId, dynamicCode, password);
  }

  /// 加载用户
  Future<void> _loadUser(XTarget person) async {
    await stopWatch("加载${person.name}用户", () async {
      try {
        _user = Person(person);
        XLogUtil.i(_user);
        _work.value = WorkProvider(this);
        _box = BoxProvider(this);
        _chatProvider = ChatProvider(_user!);
        _home = HomeProvider(this);
        XLogUtil.dd('>>>>>>User._loadUser');
        await _refresh();
      } catch (e, s) {
        var t = DateUtil.formatDate(DateTime.now(),
            format: "yyyy-MM-dd HH:mm:ss.SSS");
        errInfo += '$t $e ==== $s';
        XLogUtil.e('>>>>>>User._loadUser.err $s');
        changeCallback(args: [false]);
        RoutePages.to(path: Routers.errorGuide);
      } finally {
        // release();
        _inited = true;
      }
    });
  }

  /// 重载数据
  Future<void> _refresh() async {
    _inited = false;
    try {
      await _user?.deepLoad(reload: true);
      await work?.loadTodos(reload: true);
      await _chatProvider?.load(reload: true);
      // await _home?.loadConfig();
      XLogUtil.dd('>>>>>>User._refresh');
      changeCallback(args: [true]);
    } catch (e, s) {
      var t = DateUtil.formatDate(DateTime.now(),
          format: "yyyy-MM-dd HH:mm:ss.SSS");
      errInfo += '$t $e ==== $s';
      // ToastUtils.showMsg(msg: errInfo);
      // SystemUtils.copyToClipboard(errInfo);
      XLogUtil.dd('>>>>>>User._refresh.error,$e $s');
      changeCallback(args: [false]);
      RoutePages.to(path: Routers.errorGuide);
    } finally {
      _inited = true;
    }
    // command.emitterFlag();
  }

  /// 唤醒
  Future<void> wakeUp() async {
    // if (_inited) {
      await stopWatch("数据唤醒", () async {
        // await _user?.cacheObj.all(true);
        bool? res = await _chatProvider?.wakeUp();
        await work?.loadTodos(reload: true);
        XLogUtil.dd('>>>>>>User.wakeUp');
        if (null != res && !res) {
          ToastUtils.showMsgDev(msg: "唤醒拉去数据失败");
        } else if (null == res) {
          ToastUtils.showMsgDev(msg: "唤醒系统异常");
        }
        changeCallback(args: [true]);
      });
    // } else {
    //   SystemLog.err('唤醒失败', '系统未初始化，请先初始化系统');
    // }
  }

  Future<T> stopWatch<T>(String title, Future<T> Function() callback) async {
    var startTime = DateTime.now().millisecondsSinceEpoch;
    try {
      T res = await callback();
      return res;
    } finally {
      var runTime = DateTime.now().millisecondsSinceEpoch - startTime;
      log("$title耗时：$runTime毫秒\r\n");
    }
  }

  late String errInfo = "";

  void log(String err) {
    errInfo += err;
  }
}
